﻿/************************************************************************
* Copyright (c) 2018 All Rights Reserved.
*命名空间：Wx.Sdk.Pay.Src
*文件名： Notify
*创建人： kingling
*创建时间：2018/10/18 14:01:25
*描述
*=======================================================================
*修改标记
*修改时间：2018/10/18 14:01:25
*修改人：kingling
*描述：
************************************************************************/

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Wx.Sdk.Pay.Entity;
using Wx.Sdk.Utils;

namespace Wx.Sdk.Pay.Src
{
    public abstract class Notify : INotify
    {
        WxPay wxPay;
        HttpContext context;
        public Notify(WxPay wxPay)
        {
            this.wxPay = wxPay;
            context = wxPay.httpContextAccessor.HttpContext;
        }
        string INotify.Refund()
        {
            using (Stream stream = context.Request.Body)
            {

                byte[] bytes = new byte[context.Request.ContentLength.Value];
                stream.Read(bytes, 0, bytes.Length);
                stream.Dispose();
                string postString = Encoding.UTF8.GetString(bytes);
                var msg = new PayMsg();
                if (postString.IsNull())
                {
                    return XmlHelper.ToXml(msg);
                }
                //序列化
                var result = XmlHelper.ToObject<RefundNotify>(postString);
                if (result == null)
                {
                    return XmlHelper.ToXml(msg);
                }
                if (result.return_code != "SUCCESS")
                {
                    return XmlHelper.ToXml(msg);
                }
                //解密
                var key = EncyptHelper.ToMD5(wxPay.payOption.sign_key);
                var res = XmlHelper.ToObject<RefundNotifyInfo>(EncyptHelper.AesDecrypt(result.req_info, key));
                //抽象

                if (this.Refund(res))
                {
                    msg.return_code = "SUCCESS";
                    msg.return_msg = "OK";
                }
                return XmlHelper.ToXml(msg);

            }
        }

        string INotify.Pay()
        {
            using (Stream stream = context.Request.Body)
            {
                byte[] bytes = new byte[context.Request.ContentLength.Value];
                stream.Read(bytes, 0, bytes.Length);
                stream.Dispose();
                string postString = Encoding.UTF8.GetString(bytes);
                var msg = new PayMsg();
                if (postString.IsNull())
                {
                    return XmlHelper.ToXml(msg);
                }
                //序列化
                var result = XmlHelper.ToObject<PayNotify>(postString);
                if (result == null)
                {
                    return XmlHelper.ToXml(msg);
                }
                if (result.return_code != "SUCCESS")
                {
                    return XmlHelper.ToXml(msg);
                }
                if (result.result_code != "SUCCESS")
                {
                    return XmlHelper.ToXml(msg);
                }
                //验证
                var sign = result.sign;
                var sign_type = result.sign_type;
                result.sign = null;
                result.sign_type = null;
                var str = ModelHelper.ToUrlParameter(result) + $"&key={wxPay.payOption.sign_key}";
                result.sign = sign_type.ToUpper() == "MD5" ? EncyptHelper.ToMD5(str, false) : EncyptHelper.ToHMACSHA256(str, wxPay.payOption.sign_key);
                if (sign == result.sign && Pay(result))
                {
                    msg.return_code = "SUCCESS";
                    msg.return_msg = "OK";
                }
                return XmlHelper.ToXml(msg);

            }
        }
        #region 抽象方法
        protected abstract bool Refund(RefundNotifyInfo refundNotifyInfo);
        protected abstract bool Pay(PayNotify payNotify);
        #endregion
    }
}
